/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package kasanova.sis.repositorio;

import kasanova.sis.repositorio.ex.DirNotFoundException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import kasanova.sis.jsf.FileUploadController;

/**
 * Utilitarian class for files manipulation of the client
 *
 * @author Rafael
 */
public class DataStorage implements Serializable {

    /**
     *
     * @param pathDir
     * @return
     */
    public Boolean createDir(String pathDir) {
        File dir = new File(pathDir);
        return dir.mkdir();
    }

    /**
     *
     * @param pathName
     * @return
     * @throws FileNotFoundException
     */
    public Boolean deleteFiles(String pathName) throws FileNotFoundException {
        File file = new File(pathName);

        if (file.exists()) {
            if (file.isDirectory()) {
                String[] children = file.list();
                for (int i = 0; i < children.length; i++) {

                    boolean success = deleteFiles(pathName + File.separatorChar + children[i]);
                    if (!success) {
                        return false;
                    }
                }
            }
            return file.delete();
        }
        throw new FileNotFoundException();
    }

    /**
     *
     * @param pathDir
     * @return
     * @throws DirNotFoundException
     */
    public String[] readerFileNames(String pathDir) throws DirNotFoundException {
        File dir = new File(pathDir);
        if (dir.exists() && dir.isDirectory()) {
            return dir.list();
        }
        throw new DirNotFoundException();
    }

    /**
     *
     * @param pathDir
     * @return
     * @throws DirNotFoundException
     */
    public Float[] readerFilesSize(String pathDir) throws DirNotFoundException {
        File dir = new File(pathDir);
        File[] files;
        if (dir.exists() && dir.isDirectory()) {
            files = dir.listFiles();

            Float[] filesSize = new Float[files.length];

            for (int i = 0; i < files.length; i++) {
                if (files[i].isFile()) {
                    filesSize[i] = ((float) files[i].length() / (float) 1024);
                } else {
                    filesSize[i] = 0.0f;
                }
            }

            return filesSize;
        }
        throw new DirNotFoundException();
    }

    /**
     *
     * @param pathDir
     * @param newPathDir
     * @return
     * @throws DirNotFoundException
     */
    public Boolean updateDir(String pathDir, String newPathDir) throws DirNotFoundException {
        File dir = new File(pathDir);
        if (dir.exists() && dir.isDirectory()) {
            return dir.renameTo(new File(newPathDir));
        }
        throw new DirNotFoundException();
    }

    /**
     * Obs: mudar o indioma desse comentário de português para inglês.
     *
     * Copia os arquivos ou diretório para outro destino qualquer.
     *
     * @param pathNow String que representa o caminho do arquivo de origem dos
     * arquivos
     * @param pathAfter String que representa o caminho do arquivo de destino
     * dos arquivos
     */
    public boolean copyFiles(String pathNow, String pathAfter) {
        try {
            File origem = new File(pathNow);
            File[] ListSubArquivos = origem.listFiles();
            System.out.println("Copiando arquivos de:\n" + pathNow
                    + " para:" + pathAfter);
            for (File subArquivo : ListSubArquivos) {
                if (!subArquivo.isDirectory()) {
                    System.out.println("\nprocessando " + subArquivo.getName() + "...");
                    File arquivo = new File(pathAfter + subArquivo.getName());

                    DataHandler fileHandler = new DataHandler(new FileDataSource(subArquivo));

                    FileOutputStream in = new FileOutputStream(arquivo);

                    fileHandler.writeTo(in);

                    in.close();

                    System.out.println("Arquivo recebido com sucesso!");
                } else {
                    File dir = new File(pathAfter + File.separatorChar + subArquivo.getName());
                    if (!dir.exists()) {
                        dir.mkdir();
                    }
                    copyFiles(pathNow + subArquivo.getName() + File.separatorChar,
                            pathAfter + subArquivo.getName() + File.separatorChar);
                }
            }
        } catch (IOException ex) {
            System.out.println("Erro:" + ex.getMessage());
            return false;
        }
        System.out.println("Cópia dos Arquivos Completa...");
        return true;
    }

    /**
     *
     * @param pathDir
     * @param nameFile
     * @param fileHandler
     * @return
     */
    public Boolean createFile(String pathDir, String nameFile, DataHandler fileHandler) {
        File file = new File(pathDir + File.separatorChar + nameFile);
        System.out.println(">>>>>>>>>>" + pathDir + File.separatorChar + nameFile);
        try {
            FileOutputStream out = new FileOutputStream(file);
            fileHandler.writeTo(out);
            out.close();
            return true;
        } catch (IOException ex) {
            Logger.getLogger(DataStorage.class.getName()).log(Level.SEVERE, null, ex);
        }

        return false;
    }

    /**
     *
     * @param pathDir
     * @param fileName
     * @param in
     * @return
     */
    public Boolean createFile(String pathDir, String fileName, InputStream in) {

        File file = new File(pathDir + File.separatorChar + fileName);
        try {
            // write the inputStream to a FileOutputStream
            OutputStream out = new FileOutputStream(file);

            int read = 0;
            byte[] bytes = new byte[1024];
            while ((read = in.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }
            in.close();
            out.flush();
            out.close();
            return true;
        } catch (IOException ex) {
            Logger.getLogger(DataStorage.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

    /**
     *
     * @param pathDir
     * @param nameFile
     * @return
     * @throws FileNotFoundException
     * @throws DirNotFoundException
     */
    public DataHandler readerFile(String pathDir, String nameFile) throws FileNotFoundException, DirNotFoundException {

        if (new File(pathDir).exists() && new File(pathDir).isDirectory()) {

            Set<String> namesFiles = new HashSet<String>(Arrays.asList(readerFileNames(pathDir)));

            if (namesFiles.contains(nameFile)) {

                File file = new File(pathDir + File.separatorChar + nameFile);

                DataHandler handler = new DataHandler(new FileDataSource(file));
                return handler;
            }
            throw new FileNotFoundException();
        }
        throw new DirNotFoundException();
    }

    public byte[] readerFileBytes(String pathDir, String nameFile) throws FileNotFoundException, DirNotFoundException {

        if (new File(pathDir).exists() && new File(pathDir).isDirectory()) {

            Set<String> namesFiles = new HashSet<String>(Arrays.asList(readerFileNames(pathDir)));

            if (namesFiles.contains(nameFile)) {

                File file = new File(pathDir + File.separatorChar + nameFile);
                byte[] bytes = new byte[(int) file.length()];
                FileInputStream stream = new FileInputStream(file);
                try {
                    stream.read(bytes);
                } catch (IOException ex) {
                    Logger.getLogger(DataStorage.class.getName()).log(Level.SEVERE, null, ex);
                }

                return bytes;
            }
            throw new FileNotFoundException();
        }
        throw new DirNotFoundException();
    }

    /**
     *
     * @param pathName
     * @return
     */
    public Boolean existed(String pathName) {
        File file = new File(pathName);
        return file.exists();
    }

    /**
     *
     * @param pathName
     * @return
     */
    public Boolean isDirectory(String pathName) {
        File file = new File(pathName);
        return file.isDirectory();
    }

    /**
     *
     * @param pathName
     * @return
     */
    public Boolean isFile(String pathName) {
        File file = new File(pathName);
        return file.isFile();
    }
}
